#include <reg52.h>
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int

//管脚定义
sbit IRED=P3^2;
sbit pwm = P0^0;
sbit sw1 = P3^3;
sbit sw2 = P3^4;
bit New_rec = 0, Send_ed = 1;
uint UART_buff;
//TODO:让每个对应的值相等，即angle是多少就是多少度
//5对应0度 10对应45度 15对应90度 20对应135度 25对应180度
uint angle=0;//调整初始角度为0°
uint count=0;
int i=0;
unsigned int ired_buf[3];
unsigned int gired_data[4];
unsigned int gsmg_code[17];
//共阴极数码管显示0~F的段码数据
unsigned int gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
				0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void delay_10us(unsigned char ten_us)
{
	while(ten_us--);	
}

void delay(uint ms)
{
	uint i, j;
	for(i=0;i<ms;i++)
		for(j=0;j<112;j++);
}

void Init()
{
	//红外接收初始化
	IT0=1;	//下降沿触发
	EX0=1;	//打开中断0允许
	EA=1;	//打开总中断
	IRED=1;	//初始化端口
	
	//Time0_init
	TMOD |= 0x01;//定时器零工作方式1
	TL0 = 0xA3;
	TH0 = 0xFF;//初始值500us
	ET0 = 1;
	TF0 = 0;//清除TF0标志
	TR0 = 1;//定时器开始计时
	
	//接收中断初始化
	SCON=0x50;//设定串口工作方式0101 0000
	PCON=0x00;
	TMOD |=0x20;
	TL1=0xfd;//波特率9600
	TH1=0xfd;
	TR1=1;
	
	
	EA = 1;
	ES  = 1;       //开中断
	
}

void main()
{
	Init();//初始化
	while(1)
	{
		
		ired_buf[0]=gsmg_code[gired_data[2]/16];//将控制码高4位转换为数码管段码
		ired_buf[1]=gsmg_code[gired_data[2]%16];//将控制码低4位转换为数码管段码
		ired_buf[2]=0X76;//显示H
		//smg_display(ired_buf,6);	
		if(ired_buf[0]=='0' && ired_buf[1]=='c')
		{
			sw1=0;
			sw2=1;
		}
		else if(ired_buf[0]=='1'&& ired_buf[1]=='6')
		{
			sw2=0;
			sw1=1;
		}
		
		if(sw1==0)
		{
			//当angle=180时，只能按sw2，按sw1不起作用
			if(angle<180)
			{
				for(i=0;i<=180;i++)
				{
					angle=i;
					delay(2);
				}
			}
			count=0;
			while(sw1==0);//直到松手才跳出循环
		}
		if(sw2==0)
		{
			//当angle=0时，只能按sw1，按sw2不起作用
			if(angle>0)
			{
				for(i=180;i>=0;i--)
				{
					angle=i;
					delay(2);
				}
			}
			if(angle<=0)angle=0;
			count=0;
			while(sw2==0);
		}
	}
}

void ired() interrupt 0	//外部中断0服务函数
{
	unsigned int ired_high_time=0;
	unsigned char time_cnt=0;
	unsigned int i=0,j=0;

	if(IRED==0)
	{
		time_cnt=1000;
		while((!IRED)&&(time_cnt))//等待引导信号9ms低电平结束，若超过10ms强制退出
		{
			delay_10us(1);//延时约10us
			time_cnt--;
			if(time_cnt==0)return;		
		}
		if(IRED)//引导信号9ms低电平已过，进入4.5ms高电平
		{
			time_cnt=500;
			while(IRED&&time_cnt)//等待引导信号4.5ms高电平结束，若超过5ms强制退出
			{
				delay_10us(1);
				time_cnt--;
				if(time_cnt==0)return;	
			}
			for(i=0;i<4;i++)//循环4次，读取4个字节数据
			{
				for(j=0;j<8;j++)//循环8次读取每位数据即一个字节
				{
					time_cnt=600;
					while((IRED==0)&&time_cnt)//等待数据1或0前面的0.56ms结束，若超过6ms强制退出
					{
						delay_10us(1);
						time_cnt--;
						if(time_cnt==0)return;	
					}
					time_cnt=20;
					while(IRED)//等待数据1或0后面的高电平结束，若超过2ms强制退出
					{
						delay_10us(10);//约0.1ms
						ired_high_time++;
						if(ired_high_time>20)return;	
					}
					gired_data[i]>>=1;//先读取的为低位，然后是高位
					if(ired_high_time>=8)//如果高电平时间大于0.8ms，数据则为1，否则为0
						gired_data[i]|=0x80;
					ired_high_time=0;//重新清零，等待下一次计算时间
					
					
				}
			}
		}
		if(gired_data[2]!=~gired_data[3])//校验控制码与反码，错误则返回
		{
			for(i=0;i<4;i++)
				gired_data[i]=0;
			return;	
		}
	}		
}

void Timer() interrupt 1 //中断程序pwm信号输出
{
	TL0 = 0xA3;
	TH0 = 0xFF;

	count++;
	if(count == 20)count = 0;
	if(count < angle/6)pwm = 1;
	else pwm = 0;
}

void ser_int (void) interrupt 4
{
	if(RI == 1) 
	{
		ES=0;		//暂时关闭串口中断
		//如果收到.
		RI = 0;      //清除标志.
		New_rec = 1;
		UART_buff = SBUF;  //把收到的信息从SBUF放到UART_buff中
		if(UART_buff==0x36)  
		{
			sw1=0;
			sw2=1;
		}
		else if(UART_buff==0x35)
		{
			sw1=1;
			sw2=0;
		}
		else
		{
			
		}
	}
	else
	{        //如果送毕.
      TI = 0;      //清除标志.
      Send_ed = 1;
    }
	ES=1;//开启串口中断
}